package net.liuzd.spring.boot.v2.service;

import java.io.File;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service("phantomjsService")
public class PhantomjsService {

    private static final Logger log = LoggerFactory.getLogger(PhantomjsService.class);

    @Value("${phantomjs.exec.path}")
    private String              phantomjsExecPath;

    @Value("${phantomjs.echarts.get.base64.call.java.url}")
    private String              echartsBase64ToJavaUrl;
    //
    @Value("${phantomjs.call.java.url}")
    private String              phantomjsUrl;

    @Value("${image.width}")
    private String              imgWidth;
    @Value("${image.height}")
    private String              imgHeight;
    //
    @Value("${image.root.path}")
    private String              imgRooPath;

    private static String       SP  = " ";

    private static String getResouceLibrary() {
        StringBuilder library = new StringBuilder();
        library.append(PhantomjsService.class.getClass().getResource("/phantomjs").getPath());
        if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
            library.replace(0, 1, "");
        }
        return library.append("pageOpen.js").toString();
    }

    private String getCmd(String url) {
        StringBuilder cmd = new StringBuilder();
        cmd.append(phantomjsExecPath).append(SP);
        cmd.append(getResouceLibrary()).append(SP);
        cmd.append(url).append(SP);
        cmd.append(imgWidth + "*" + imgHeight).append(SP);
        return cmd.toString();
    }

    public void exec(String url) {
        Runtime rt = Runtime.getRuntime();
        String cmdStr = getCmd(url);
        log.info("执行命令：{}", cmdStr);
        try {
            rt.exec(cmdStr);
        } catch (IOException e) {
            log.error("执行phantomjs的指令失败！请检查是否安装有PhantomJs的环境或配置path路径！PhantomJs详情参考这里:http://phantomjs.org", e);
        }
        log.info("打开地址完成！");
    }

    private PhantomJSDriver initPhantomjs() {
        // 设置必要参数
        DesiredCapabilities dcaps = new DesiredCapabilities();
        // ssl证书支持
        dcaps.setCapability("acceptSslCerts", true);
        // 截屏支持
        dcaps.setCapability("takesScreenshot", true);
        // css搜索支持
        dcaps.setCapability("cssSelectorsEnabled", true);
        // js支持
        dcaps.setJavascriptEnabled(true);
        // 驱动支持（第二参数表明的是你的phantomjs引擎所在的路径）
        String osname = System.getProperties().getProperty("os.name");
        if (osname.equals("Linux")) {// 判断系统的环境win or Linux
            dcaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, phantomjsExecPath);
        } else {
            dcaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, phantomjsExecPath + ".exe");
        }
        // 创建无界面浏览器对象
        PhantomJSDriver driver = new PhantomJSDriver(dcaps);
        // 设置隐性等待（作用于全局）
        driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
        //
        return driver;
    }

    @PostConstruct
    private void init() throws IOException {
        // 通过调用myChart.getDataURL()得到base64，调用java直接生成图片
        exec(echartsBase64ToJavaUrl);
        sleep();
        // 通过Java程序截图整个网页，直接调用图片不正确（黑色图片，无数据），可通过请求访问生成
        execPhantomJs(phantomjsUrl);
    }

    public void execPhantomJs(String phantomjsUrl) throws IOException {
        long start = System.currentTimeMillis();
        //
        PhantomJSDriver driver = initPhantomjs();
        driver.get(phantomjsUrl);
        //
        JavascriptExecutor js = driver;
        js.executeScript("window.scrollBy(0,1000)");
        //
        File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
        // 利用FileUtils工具类的copyFile()方法保存getScreenshotAs()返回的文件对象
        UUID uuid = UUID.randomUUID();
        String name = uuid.toString() + ".png";
        FileUtils.copyFile(srcFile, new File(imgRooPath + File.separator + name));
        System.out.println("耗时：" + (System.currentTimeMillis() - start) + " 毫秒");
    }

    @SuppressWarnings("unused")
    private void sleep() {
        try {
            Thread.sleep(8000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
